using MediatR;
using WMS.Domain;
using WMS.ErrorCode;
using WMS.Infrasturcture.Interfaces;
using WMS.WebApiRead.Application.Command;
using WMS.WebApiRead.DTO;

namespace WMS.WebApiRead.Application.Commandhandler
{
    /// <summary>
    /// 盘点信息查询命令处理器（多表联查+分页）
    /// 联查：盘点表、盘点明细表、上传附件表、经办人信息表、仓库表、库管部门表、盘点类型表
    /// </summary>
    public class InventoryQueryCommandHandler : IRequestHandler<InventoryQueryCommand, ApiResult<ApiPaging<List<InventoryQueryResultDTO>>>>
    {
        private readonly IBaseRepository<InventoryInfo> inventoryRepository;
        private readonly IBaseRepository<Inventory_check_details> detailsRepository;
        private readonly IBaseRepository<Uploadattachment> attachmentRepository;
        private readonly IBaseRepository<HandlerInfo> handlerRepository;
        private readonly IBaseRepository<WarehouseInfo> warehouseRepository;
        private readonly IBaseRepository<WarehouseDept> deptRepository;
        private readonly IBaseRepository<InventoryTypeInfo> inventoryTypeRepository;

        /// <summary>
        /// 构造函数，注入所有需要的仓储
        /// </summary>
        public InventoryQueryCommandHandler(
            IBaseRepository<InventoryInfo> inventoryRepository,
            IBaseRepository<Inventory_check_details> detailsRepository,
            IBaseRepository<Uploadattachment> attachmentRepository,
            IBaseRepository<HandlerInfo> handlerRepository,
            IBaseRepository<WarehouseInfo> warehouseRepository,
            IBaseRepository<WarehouseDept> deptRepository,
            IBaseRepository<InventoryTypeInfo> inventoryTypeRepository)
        {
            this.inventoryRepository = inventoryRepository;
            this.detailsRepository = detailsRepository;
            this.attachmentRepository = attachmentRepository;
            this.handlerRepository = handlerRepository;
            this.warehouseRepository = warehouseRepository;
            this.deptRepository = deptRepository;
            this.inventoryTypeRepository = inventoryTypeRepository;
        }

        /// <summary>
        /// 处理盘点信息查询命令（多表联查+分页）
        /// </summary>
        public async Task<ApiResult<ApiPaging<List<InventoryQueryResultDTO>>>> Handle(InventoryQueryCommand request, CancellationToken cancellationToken)
        {
            try
            {
                // ==================== 多表联查 ====================
                // 主表：InventoryInfo（盘点表）
                // LEFT JOIN WarehouseInfo（仓库表）
                // LEFT JOIN HandlerInfo（经办人信息表）
                // LEFT JOIN WarehouseDept（库管部门表）
                // LEFT JOIN InventoryTypeInfo（盘点类型表）
                var query = from inventory in inventoryRepository.GetAll()
                            where !inventory.IsDeleted // 只查询未删除的记录
                            join warehouse in warehouseRepository.GetAll()
                            on inventory.WarehouseId equals warehouse.WarehouseID into warehouseGroup
                            from warehouse in warehouseGroup.DefaultIfEmpty()
                            join handler in handlerRepository.GetAll()
                            on inventory.HandlerrId equals handler.HandlerrId into handlerGroup
                            from professional in handlerGroup.DefaultIfEmpty()
                            join dept in deptRepository.GetAll()
                            on (warehouse != null ? warehouse.WarehouseDeptId : (professional != null ? professional.WarehouseDeptId : 0)) equals dept.WarehouseDeptId into deptGroup
                            from dept in deptGroup.DefaultIfEmpty()
                            join inventoryType in inventoryTypeRepository.GetAll()
                            on inventory.InventoryTypeId equals inventoryType.InventoryTypeId into inventoryTypeGroup
                            from inventoryType in inventoryTypeGroup.DefaultIfEmpty()
                            select new
                            {
                                Inventory = inventory,
                                WarehouseName = warehouse != null ? warehouse.WarehouseName : "未分配",
                                WarehouseId = warehouse != null ? warehouse.WarehouseID : 0,
                                HandlerName = professional != null ? professional.HandlerName : "未分配",
                                HandlerrId = professional != null ? professional.HandlerrId : 0,
                                WarehouseDeptId = dept != null ? dept.WarehouseDeptId : (int?)null,
                                WarehouseDeptName = dept != null ? dept.WarehouseDeptName : "未分配",
                                InventoryTypeId = inventoryType != null ? inventoryType.InventoryTypeId : 0,
                                InventoryTypeName = inventoryType != null ? inventoryType.InventoryTypeName : "未分配"
                            };

                // ==================== 条件筛选 ====================
                // 1. 盘点单号（盘点编号）- 精确查询
                if (!string.IsNullOrEmpty(request.QueryDTO.InventoryCode))
                {
                    query = query.Where(x => x.Inventory.InventoryCode.Contains(request.QueryDTO.InventoryCode));
                }

                // 2. 盘点状态（字符串类型，需要转换为int）
                if (!string.IsNullOrEmpty(request.QueryDTO.DataStatus))
                {
                    if (int.TryParse(request.QueryDTO.DataStatus, out int dataStatus))
                    {
                        query = query.Where(x => x.Inventory.DataStatus == dataStatus);
                    }
                }

                // 3. 盘点开始时间（时间范围查询）
                if (request.QueryDTO.InventoryStartDateTime.HasValue)
                {
                    query = query.Where(x => x.Inventory.InventoryDateTime >= request.QueryDTO.InventoryStartDateTime.Value);
                }

                // 4. 盘点结束时间（时间范围查询）
                if (request.QueryDTO.InventoryEndDateTime.HasValue)
                {
                    query = query.Where(x => x.Inventory.InventoryEndTime <= request.QueryDTO.InventoryEndDateTime.Value);
                }

                // 5. 制单人（创建人）- 精确查询
                if (!string.IsNullOrEmpty(request.QueryDTO.CreateName))
                {
                    query = query.Where(x => x.Inventory.CreateName == request.QueryDTO.CreateName);
                }

                // 6. 部门ID（库管部门ID）
                if (request.QueryDTO.WarehouseDeptId > 0)
                {
                    query = query.Where(x => x.WarehouseDeptId == request.QueryDTO.WarehouseDeptId.Value);
                }

                // 7. 仓库ID
                if (request.QueryDTO.WarehouseId>0)
                {
                    query = query.Where(x => x.Inventory.WarehouseId == request.QueryDTO.WarehouseId.Value);
                }

                // 8. 仓库名称（模糊查询）
                if (!string.IsNullOrEmpty(request.QueryDTO.WarehouseName))
                {
                    query = query.Where(x => x.WarehouseName.Contains(request.QueryDTO.WarehouseName));
                }

                // 9. 经办人名称（模糊查询）
                if (!string.IsNullOrEmpty(request.QueryDTO.HandlerName))
                {
                    query = query.Where(x => x.HandlerName.Contains(request.QueryDTO.HandlerName));
                }

                // 计算总记录数
                var totalCount = query.Count();

                // 计算总页数
                var totalPage = (int)Math.Ceiling((double)totalCount / request.QueryDTO.PageSize);

                // 执行分页查询并投影到DTO
                var inventoryList = query
                    .OrderByDescending(x => x.Inventory.CreateTime) // 按创建时间倒序
                    .Skip((request.QueryDTO.PageIndex - 1) * request.QueryDTO.PageSize)
                    .Take(request.QueryDTO.PageSize)
                    .ToList();

                // 转换为结果DTO，并查询明细表中的货品名称和附件数量
                var resultList = new List<InventoryQueryResultDTO>();

                foreach (var item in inventoryList)
                {
                    // 查询明细表中的货品名称（去重）
                    var productNames = detailsRepository.GetAll()
                        .Where(x => x.InventoryCode == item.Inventory.InventoryCode && !string.IsNullOrEmpty(x.DetailsProductName))
                        .Select(x => x.DetailsProductName)
                        .Distinct()
                        .ToList();

                    // 查询附件数量
                    var attachmentCount = attachmentRepository.GetAll()
                        .Count(x => x.InventoryCode == item.Inventory.InventoryCode && !x.IsDeleted);

                    resultList.Add(new InventoryQueryResultDTO
                    {
                        InventoryId = item.Inventory.InventoryId,
                        InventoryCode = item.Inventory.InventoryCode,
                        InventoryTypeId = item.Inventory.InventoryTypeId,
                        InventoryTypeName = item.InventoryTypeName, // 盘点类型名称（联表查询得到）
                        WarehouseId = item.Inventory.WarehouseId,
                        WarehouseName = item.WarehouseName,
                        HandlerrId = item.Inventory.HandlerrId,
                        HandlerName = item.HandlerName,
                        WarehouseDeptId = item.WarehouseDeptId,
                        WarehouseDeptName = item.WarehouseDeptName,
                        InventoryDateTime = item.Inventory.InventoryDateTime,
                        InventoryEndTime = item.Inventory.InventoryEndTime,
                        InventoryContent = item.Inventory.InventoryContent,
                        InventoryQuantity = item.Inventory.InventoryQuantity,
                        SurplusQuantity = item.Inventory.SurplusQuantity,
                        InventoryShortageQuantity = item.Inventory.InventoryShortageQuantity,
                        SurplusAmount = item.Inventory.SurplusAmount,
                        InventoryLossAmount = item.Inventory.InventoryLossAmount,
                        DataStatus = item.Inventory.DataStatus,
                        CreateName = item.Inventory.CreateName,
                        CreateTime = item.Inventory.CreateTime,
                        ProductNames = string.Join(", ", productNames), // 多个货品名称用逗号分隔
                        AttachmentCount = attachmentCount,
                        IsDeleted = item.Inventory.IsDeleted
                    });
                }

                // 返回分页结果
                return new ApiResult<ApiPaging<List<InventoryQueryResultDTO>>>
                {
                    Code = ApiResultEnum.查询成功,
                    Message = "查询盘点信息成功",
                    Data = new ApiPaging<List<InventoryQueryResultDTO>>
                    {
                        TotalCount = totalCount,
                        TotalPage = totalPage,
                        Data = resultList
                    }
                };
            }
            catch (Exception ex)
            {
                return new ApiResult<ApiPaging<List<InventoryQueryResultDTO>>>
                {
                    Code = ApiResultEnum.查询失败,
                    Message = $"查询盘点信息异常：{ex.Message}",
                    Data = new ApiPaging<List<InventoryQueryResultDTO>>
                    {
                        TotalCount = 0,
                        TotalPage = 0,
                        Data = new List<InventoryQueryResultDTO>()
                    }
                };
            }
        }
    }
}

